/** @file   ui.c
    @author M. P. Hayes, UCECE
    @date   21 August 2007
    @brief  User interface for temperature controller.
*/
#include "config.h"
#include "display.h"
#include "button.h"

/* Define button parameters.  */
enum {UI_BUTTON_POLL_RATE = 50};
enum {UI_BUTTON_HOLD_MS = 500};


/* Define setpoint default and limits.  */
enum {UI_TEMP_SETPOINT_DEFAULT = 20,
      UI_TEMP_SETPOINT_MIN = 20,
      UI_TEMP_SETPOINT_MAX = 60};


/* Define buttons.  */    
static const button_cfg_t buttons_cfg[] =
{
    BUTTON_CFG (BUTTON1_PORT, BUTTON1_BIT),
    BUTTON_CFG (BUTTON2_PORT, BUTTON2_BIT),
};

enum {UI_BUTTON_LEFT, UI_BUTTON_RIGHT, UI_BUTTONS_NUM};


/** Private variables.  */
static button_obj_t buttons[UI_BUTTONS_NUM];
static uint8_t button_hold_count;
static uint8_t button_ticks;
static uint8_t button_poll_ticks;
static uint8_t temp_setpoint;
static uint8_t temp_current;
static bool error = FALSE;

/** Display a temperature.
    @param temp temperature to display, must be less than 100  */
static void 
ui_display_temp (uint8_t temp)
{
    char buffer[4];

    /* This only works if temp < 100.  */
    buffer[0] = temp / 10 + '0';
    buffer[1] = temp % 10 + '0';
    buffer[2] = '$';
    buffer[3] = '\0';
	
	display_puts (buffer);
}

/** Get the setpoint temperature.
    @return the setpoint temperature  */
uint8_t ui_temp_setpoint_get (void)
{
    return temp_setpoint;
}


/** Set the current temperature for display.
    @param temp current temperature  */
void ui_temp_current_set (uint8_t temp)
{
	error = FALSE;
	if (temp_current != temp){
		temp_current = temp;
		ui_display_temp(temp_current);
	}
}


/** Poll and process buttons.  */
/*There is a bug in here somewhere*/
static void
ui_buttons_poll (void)
{
	static int16_t wait_for_it = 0; //times the delay between the displaying the 
	//setpoint and going back to the actual
    uint8_t i;

    /* Poll and debounce the buttons.  */
    for (i = 0; i < UI_BUTTONS_NUM; i++)
	button_poll (buttons + i);

    if (button_pushed_p (buttons + UI_BUTTON_LEFT))
    {
    	if (!error && temp_setpoint > UI_TEMP_SETPOINT_MIN){
		temp_setpoint--;
		display_puti(temp_setpoint);
		wait_for_it = 0;
		}
    }
    else if (button_pushed_p (buttons + UI_BUTTON_RIGHT))
    {
	
		if (!error && temp_setpoint < UI_TEMP_SETPOINT_MAX) {
		temp_setpoint++;
		display_puti(temp_setpoint);
		wait_for_it = 0;
		}
    }
    else{
    	 if (wait_for_it != -1) wait_for_it++;
    	 if (button_poll_ticks*5 == wait_for_it){
    	 	ui_display_temp(temp_current);
    	 	wait_for_it = -1;
    	 }
    }
}


/** Update display and poll buttons.  */
void ui_update (void)
{
    button_ticks++;
    if (button_ticks >= button_poll_ticks)
    {
		button_ticks = 0;
		ui_buttons_poll ();
    }

    display_update ();
}


/** Initialise user interface.
    @param update_rate the rate that \c ui_update called  */
void ui_init (uint16_t update_rate)
{
    uint8_t i;

    /* Initialise each of the buttons.  */
    for (i = 0; i < UI_BUTTONS_NUM; i++)
	button_init (buttons + i, buttons_cfg + i);

    /* Determine how often to poll buttons.  */
    button_poll_ticks = update_rate / UI_BUTTON_POLL_RATE;
    button_ticks = 0;

    /* Set required number of calls to button_poll before button
       considered debounced.  */
    button_poll_count_set (BUTTON_POLL_COUNT (UI_BUTTON_POLL_RATE));

    /* Determine how many calls to button_poll before button
       considered held for a long push.  */
    button_hold_count = update_rate * UI_BUTTON_HOLD_MS / 1000; 

    display_init (update_rate);

    temp_setpoint = UI_TEMP_SETPOINT_DEFAULT;
}
/** Display an error code, from the control module
@param error code from 0 - 9 */
void ui_error_set(uint8_t error_code)
{
	//if (!error){
	char err_buffer[] = {'E','R','R',error_code + '0','\0'};
	display_puts (err_buffer);
	error = TRUE;
	//}
}
